#include "export_yaml_file.h"
#include <yaml-cpp/yaml.h>
#include <iostream>
#include <dbms/dbms_channel.h>
#include <dbms/dbms_device.h>
#include <dbms/dbms_fd_handler.h>

namespace iot_acq {
ExportYamlFile::ExportYamlFile() {}

ExportYamlFile::~ExportYamlFile() {}

bool ExportYamlFile::ExportYaml(const std::string &filePath)
{
	YAML::Node root;
	if (!ExportRoot(root)) {
		HTELINK_LOG_ERR("export file %s failed", filePath);
		return false;
	}
	std::ofstream fout(filePath);
	fout << root;
	fout.close();
	return true;
}
bool ExportYamlFile::ExportRoot(YAML::Node &root)
{
	root["channels"] = ExportChannels();
	root["devices"] = ExportDevices();
	return true;
}

YAML::Node ExportYamlFile::ExportChannels()
{
	YAML::Node channelNode;
	dbms::DbmsChannel dbmsChannel;
	dbmsChannel.Get([&](const dbms::DeviceChannel_t &dc) {
		YAML::Node deviceChannel;
		deviceChannel["id"] = dc.id();
		deviceChannel["timeout"] = dc.timeout();
		deviceChannel["interval"] = dc.interval();
		deviceChannel["reportPeriod"] = dc.reportperiod();
		deviceChannel["type"] = static_cast<int32_t>(dc.ctype());
		YAML::Node params;
		if (dc.ctype() == dbms::CT_COM) {
			params["name"] = dc.com().name();
			params["baudRate"] = dc.com().baudrate();
			params["dataBits"] = dc.com().databit();
			params["parity"] = dc.com().parity();
			params["stopBits"] = dc.com().stopbit();
		} else if (dc.ctype() == dbms::CT_TCP || dc.ctype() == dbms::CT_UDP) {
			params["ip"] = dc.socket().ip();
			params["port"] = dc.socket().port();
		}
		deviceChannel["params"] = params;
		channelNode.push_back(deviceChannel);
	});
	return channelNode;
}

YAML::Node ExportYamlFile::ExportDevices()
{
	YAML::Node devicesNode;
	dbms::DbmsDevice dbmsDevice;
	dbmsDevice.Get([&](const dbms::Device_t &device) {
		YAML::Node devNode;
		devNode["id"] = device.id();
		devNode["addr"] = device.addr();
		devNode["name"] = device.name();
		devNode["channelId"] = device.channelid();
		devNode["protocolId"] = device.protoid();
		YAML::Node functionsNode;
		for (int i = 0; i < device.funclist_size(); ++i) {
			YAML::Node funcNode;
			funcNode["id"] = device.funclist(i).id();
			funcNode["funcType"] = device.funclist(i).type();
			funcNode["ratio"] = device.funclist(i).ratio();
			functionsNode.push_back(funcNode);
		}
		devNode["functions"] = functionsNode;
		devicesNode.push_back(devNode);
	});
	return devicesNode;
}
YAML::Node ExportYamlFile::ExportFdHandler()
{
	YAML::Node fdNode;
	dbms::DbmsFdHandler fdHandler;
	fdHandler.Get([&](const std::string &id) {
		YAML::Node idNode;
		idNode["ID"] = id;
		fdNode.push_back(idNode);
	});
	return fdNode;
}
} // namespace iot_acq